package com.cema.manage.project.manage.withdrawalRecord.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.cema.manage.common.utils.StringUtils;
import com.cema.manage.framework.web.controller.BaseController;
import com.cema.manage.framework.web.domain.Message;
import com.cema.manage.framework.web.page.TableDataInfo;
import com.cema.manage.project.enums.MoneyTypeEnum;
import com.cema.manage.project.enums.ToExamineEnum;
import com.cema.manage.project.enums.UserEffectiveStatusEnum;
import com.cema.manage.project.enums.UserStatusEnum;
import com.cema.manage.project.manage.users.domain.Users;
import com.cema.manage.project.manage.users.service.IUsersService;
import com.cema.manage.project.manage.withdrawalRecord.domain.WithdrawalRecord;
import com.cema.manage.project.manage.withdrawalRecord.domain.WithdrawalRecordVo;
import com.cema.manage.project.manage.withdrawalRecord.service.IWithdrawalRecordService;
import com.cema.manage.zfb.AlipayFundTransUniTService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 提现记录 信息操作处理
 *
 * @author reasahi
 * @date 2024-07-08
 */
@Controller
@RequestMapping("/manage/withdrawalRecord")
public class WithdrawalRecordController extends BaseController {
    private String prefix = "manage/withdrawalRecord";

    @Autowired
    private AlipayFundTransUniTService alipayFundTransUniTService;

    @Autowired
    private IWithdrawalRecordService withdrawalRecordService;

    @Autowired
    private IUsersService usersService;

    @GetMapping()
    @RequiresPermissions("manage:withdrawalRecord:view")
    public String withdrawalRecord() {
        return prefix + "/withdrawalRecord";
    }

    @GetMapping("/pass")
    @RequiresPermissions("manage:withdrawalRecordPass:view")
    public String withdrawalRecordPass() {
        return prefix + "/withdrawalRecordPass";
    }

    @GetMapping("/refuse")
    @RequiresPermissions("manage:withdrawalRecordRefuse:view")
    public String withdrawalRecordRefuse() {
        return prefix + "/withdrawalRecordRefuse";
    }

    @GetMapping("/use/{id}")
    @RequiresPermissions("manage:withdrawalRecord:view")
    public String withdrawalRecordUse(@PathVariable("id") Integer id, Model model) {
        model.addAttribute("id", id);
        return prefix + "/withdrawalRecordUse";
    }

    /**
     * 查询用户日活列表
     */
    @ResponseBody
    @PostMapping("/use")
    public TableDataInfo listAll(WithdrawalRecordVo withdrawalRecordVo) {
        WithdrawalRecord withdrawalRecord = withdrawalRecordService.selectById(withdrawalRecordVo.getId());
        String wrDurationOfUse = withdrawalRecord.getWrDurationOfUse();
        List<WithdrawalRecordVo> withdrawalRecordVoList = JSONUtil.toList(wrDurationOfUse, WithdrawalRecordVo.class);
        return getDataTable(withdrawalRecordVoList);
    }

    /**
     * 查询提现记录列表
     */
    @RequiresPermissions("manage:withdrawalRecord:list")
    @ResponseBody
    @PostMapping("/list")
    public TableDataInfo list(WithdrawalRecordVo withdrawalRecordVo) {
        startPage();
        List<WithdrawalRecord> list = getWithdrawalRecords(withdrawalRecordVo);
        return getDataTable(list);
    }

    /**
     * 查询提现记录列表
     */
    @RequiresPermissions("manage:withdrawalRecord:list")
    @ResponseBody
    @PostMapping("/statistics")
    public JSONObject statistics(WithdrawalRecordVo withdrawalRecordVo) {
        List<WithdrawalRecord> withdrawalRecordList = getWithdrawalRecords(withdrawalRecordVo);
        Map<String, String> map = new HashMap<>(2);
        long userGoldCoinSum = 0;
        long userRedPacketSum = 0;
        long moneyCommissionGoldCoins = 0;
        long moneyCommissionRedEnvelope = 0;
        long moneyExtensionRedEnvelope = 0;
        if (ObjectUtil.isNull(withdrawalRecordList)) {
            map.put("userGoldCoin", NumberUtil.decimalFormat(",###", userGoldCoinSum));
            map.put("userRedPacket", NumberUtil.decimalFormat(",###", userRedPacketSum));
            map.put("moneyCommissionGoldCoins", NumberUtil.decimalFormat(",###", moneyCommissionGoldCoins));
            map.put("moneyCommissionRedEnvelope", NumberUtil.decimalFormat(",###", moneyCommissionRedEnvelope));
            map.put("moneyExtensionRedEnvelope", NumberUtil.decimalFormat(",###", moneyExtensionRedEnvelope));
            return new JSONObject(map);
        }
        //过滤集合
        List<WithdrawalRecord> goldCoinList = withdrawalRecordList.stream().filter(withdrawalRecord -> withdrawalRecord.getWrType().equals(MoneyTypeEnum.MONEY_GOLD_COINS.getValue())).
                collect(Collectors.toList());
        if (ObjectUtil.isNotNull(goldCoinList)) {
            userGoldCoinSum = goldCoinList.stream().mapToInt(WithdrawalRecord::getWrMoney).sum();
        }
        List<WithdrawalRecord> redPacketList = withdrawalRecordList.stream().filter(withdrawalRecord -> withdrawalRecord.getWrType().equals(MoneyTypeEnum.MONEY_RED_ENVELOPE.getValue())).
                collect(Collectors.toList());
        if (ObjectUtil.isNotNull(redPacketList)) {
            userRedPacketSum = redPacketList.stream().mapToInt(WithdrawalRecord::getWrMoney).sum();
        }
        List<WithdrawalRecord> mcgcList = withdrawalRecordList.stream().filter(withdrawalRecord -> withdrawalRecord.getWrType().equals(MoneyTypeEnum.MONEY_COMMISSION_GOLD_COINS.getValue())).
                collect(Collectors.toList());
        if (ObjectUtil.isNotNull(mcgcList)) {
            moneyCommissionGoldCoins = mcgcList.stream().mapToInt(WithdrawalRecord::getWrMoney).sum();
        }
        List<WithdrawalRecord> mcreList = withdrawalRecordList.stream().filter(withdrawalRecord -> withdrawalRecord.getWrType().equals(MoneyTypeEnum.MONEY_COMMISSION_RED_ENVELOPE.getValue())).
                collect(Collectors.toList());
        if (ObjectUtil.isNotNull(mcreList)) {
            moneyCommissionRedEnvelope = mcreList.stream().mapToInt(WithdrawalRecord::getWrMoney).sum();
        }
        List<WithdrawalRecord> mereList = withdrawalRecordList.stream().filter(withdrawalRecord -> withdrawalRecord.getWrType().equals(MoneyTypeEnum.MONEY_EXTENSION_RED_ENVELOPE.getValue())).
                collect(Collectors.toList());
        if (ObjectUtil.isNotNull(mereList)) {
            moneyExtensionRedEnvelope = mereList.stream().mapToInt(WithdrawalRecord::getWrMoney).sum();
        }
        map.put("userGoldCoin", NumberUtil.decimalFormat(",###", userGoldCoinSum));
        map.put("userRedPacket", NumberUtil.decimalFormat(",###", userRedPacketSum));
        map.put("moneyCommissionGoldCoins", NumberUtil.decimalFormat(",###", moneyCommissionGoldCoins));
        map.put("moneyCommissionRedEnvelope", NumberUtil.decimalFormat(",###", moneyCommissionRedEnvelope));
        map.put("moneyExtensionRedEnvelope", NumberUtil.decimalFormat(",###", moneyExtensionRedEnvelope));
        return new JSONObject(map);
    }

    private List<WithdrawalRecord> getWithdrawalRecords(WithdrawalRecordVo withdrawalRecordVo) {
        EntityWrapper<WithdrawalRecord> entityWrapper = new EntityWrapper<>();
        WithdrawalRecord withdrawalRecord = BeanUtil.toBean(withdrawalRecordVo, WithdrawalRecord.class);
        entityWrapper.setEntity(withdrawalRecord);
        Date endTime = withdrawalRecordVo.getEndTime();
        if (ObjectUtil.isNotNull(endTime)) {
            if (ToExamineEnum.TO_EXAMINE_RED_ENVELOPE.getValue().equals(withdrawalRecordVo.getWrStatus())) {
                entityWrapper.between("update_time", withdrawalRecordVo.getStartTime(), endTime);
            }
            if (ToExamineEnum.TO_EXAMINE_FAIL.getValue().equals(withdrawalRecordVo.getWrStatus())) {
                entityWrapper.between("refuse_time", withdrawalRecordVo.getStartTime(), endTime);
            }
            if (ToExamineEnum.TO_EXAMINE_GOLD_COINS.getValue().equals(withdrawalRecordVo.getWrStatus())) {
                entityWrapper.between("create_time", withdrawalRecordVo.getStartTime(), endTime);
            }
        }
        String nickname = withdrawalRecordVo.getNickname();
        if (StrUtil.isNotEmpty(nickname)) {
            entityWrapper.like("us_nickname", nickname, SqlLike.RIGHT);
        }
        String startWrMoney = withdrawalRecordVo.getStartWrMoney();
        String endWrMoney = withdrawalRecordVo.getEndWrMoney();
        if (StrUtil.isNotEmpty(startWrMoney) && StrUtil.isNotEmpty(endWrMoney)) {
            entityWrapper.between("wr_money", startWrMoney, Integer.parseInt(endWrMoney) + 1);
        }
        if (StrUtil.isNotEmpty(startWrMoney)) {
            entityWrapper.ge("wr_money", startWrMoney);

        }
        if (StrUtil.isNotEmpty(endWrMoney)) {
            entityWrapper.le("wr_money", endWrMoney);
        }

        entityWrapper.orderBy("create_time", false);
        return withdrawalRecordService.selectList(entityWrapper);
    }


    /**
     * 修改提现记录
     */
    @RequiresPermissions("manage:withdrawalRecord:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Integer id, Model model) {
        WithdrawalRecord withdrawalRecord = withdrawalRecordService.selectById(id);
        model.addAttribute("withdrawalRecord", withdrawalRecord);
        return prefix + "/edit";
    }

    /**
     * 保存提现记录
     */
    @RequiresPermissions("manage:withdrawalRecord:save")
    @PostMapping("/save")
    @ResponseBody
    @Transactional
    public Message save(WithdrawalRecord withdrawalRecord) {
        Integer id = withdrawalRecord.getId();
        if (StringUtils.isNotNull(id)) {
            if (ToExamineEnum.TO_EXAMINE_RED_ENVELOPE.getValue().equals(withdrawalRecord.getWrStatus())) {
                WithdrawalRecord record = withdrawalRecordService.selectById(id);
                Users users = usersService.selectById(record.getUsId());
                if (ObjectUtil.isNull(users)) {
                    return Message.error("用户不存在");
                }
                if (UserStatusEnum.USER_STATUS_VIOLATION.getValue().equals(users.getStatus())) {
                    return Message.error("用户存在违规，已封号");
                }
                withdrawalRecord.setUpdateTime(new Date());
                withdrawalRecord.setWrName(users.getAfbName());
                withdrawalRecord.setWrPhone(users.getAfbPhone());
                try {
                    Double money = record.getWrMoney() / 10000.0;
                    AlipayFundTransUniTransferResponse transferResponse = alipayFundTransUniTService.alipaySingle(users, record.getWrOrderId(), String.valueOf(money), "活动" + record.getWrType(),record.getUvChannel());
                    if (transferResponse.isSuccess()) {
                        withdrawalRecord.setWrPayOrderId(transferResponse.getPayFundOrderId());
                        //验证有邀请人
                        if (ObjectUtil.isNotNull(users.getUsParentId()) && UserEffectiveStatusEnum.USER_EFFECTIVE_STATUS_VIOLATION.getValue().equals(users.getEffective())) {
                            usersService.updateMoneyExtensionRedEnvelope(users.getUsParentId(), record.getWrMoney(),record.getUvChannel());
                            Users usersResult = new Users();
                            usersResult.setEffective(UserEffectiveStatusEnum.USER_EFFECTIVE_STATUS_NORMAL.getValue());
                            usersResult.setId(users.getId());
                            usersService.updateById(usersResult);
                        }
                    } else {
                        return Message.error(transferResponse.getSubMsg());
                    }
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                    return Message.error(e.getErrMsg());
                }
            }
            if (ToExamineEnum.TO_EXAMINE_FAIL.getValue().equals(withdrawalRecord.getWrStatus())) {
                withdrawalRecord.setRefuseTime(new Date());
            }
            if (withdrawalRecordService.updateById(withdrawalRecord)) {
                return Message.success();
            }
            return Message.error();
        } else {
            if (withdrawalRecordService.insert(withdrawalRecord)) {
                return Message.success();
            }
            return Message.error();
        }
    }
}
